package structure.queue;

/**
 * 此类的实例表示循环队列
 */
class CustomQueue {
    private Object[] data;
    /** 记录已出列的元素的个数 */
    private int front;
    /** 记录已入列与曾入列的元素的个数 */
    private int rear;

    /**
     * 创建一个具有指定大小的空队列
     * @param size
     */
    CustomQueue(int size) {
        data = new Object[size];
        front = rear = 0;
    }

    /**
     * 判断队列是否为空
     * @return
     */
    boolean isEmpty() {
        return front == rear;
    }

    /**
     * 判断队列中的元素数量是否以达到数据数组的长度
     * @return
     */
    boolean isFull() {
        return rear - front == data.length;
    }

    /**
     * 遍历队列中的每个元素
     */
    void display() {
        if (isEmpty()) {
            System.out.println("队列为空时不能遍历队列中的元素");
        } else {
            // rear与front的差等于当前队列中的元素个数
            for (int i = 0; i < rear - front; i++) {
                System.out.println(data[i]);
            }
        }
    }

    /**
     * 将元素加入队列尾部
     * @param element
     * @return
     */
    void in(Object element) {
        if (!isFull()) {
            data[rear - front] = element;
            // 将rear指针朝着列尾方向移动一个单位（值加1）
            rear++;
            System.out.println("添加元素" + element + "至队列末尾");
        } else {
            System.out.println("添加元素" + element + "至队列末尾失败：队列已满");
        }
    }

    /**
     * 将队列首位元素移出队列
     * 将队列中每个元素在数组中的索引值减1
     * @return
     */
    Object out() {
        if (isEmpty()) {
            System.out.println("队列为空时不可执行出列操作");
            return null;
        } else {
            // 获取数组中索引值0的元素（队列首位元素）
            Object element = data[0];
            // 数组中除原索引值为0的元素的索引值减1,原索引值为0的元素被覆盖
            for (int i = 1; i < rear - front; i++) {
                data[i - 1] = data[i];
                // 如果i加1的值等于rear与front的差，则将队列末位元素在数组中的原索引位置的元素设置为null
                if (i == rear - front) {
                    data[i] = null;
                }
            }
            // 将front指针朝着列尾方向移动一个单位（值加1）
            front++;
            System.out.print("移除队列的首位元素为");
            return element;
        }
    }
}
